const Binance = require('node-binance-api')
const moment = require('moment')

const auto1 = {
  APIKEY: '2CB0pSMqOczvWlli01XmC2n6qzJPXA3tus04ZTkbeTeAtFLjcdbrJN6NmonHM2we',
  APISECRET: 'XTnuZDMIktGnLlmpP3sgxqvReKawguD4tPcZDkojbZPVtu8fWGYvgov7sOd6G7Vp'
}

const binance = new Binance().options({
  urls: {
    base: 'https://api.binance.com/api/'
  },
  ...auto1
})

function countDifferenceRate (numerator, denominator) {
  denominator = parseFloat(denominator || 1) || 1
  numerator = parseFloat(numerator || 1) || 1
  return Math.round(1000000 * ((numerator - denominator) / denominator)) / 10000
}

const api = {
  // 获取交易规则
  futuresExchangeInfo () {
    return binance.futuresExchangeInfo()
  },
  futuresPrices () {
    return binance.futuresPrices()
  },
  // 保证金模式
  futuresMarginType (symbol, marginType) {
    return binance.futuresMarginType(symbol, marginType)
  },
  futuresQuote (symbol) {
    return binance.futuresQuote(symbol)
  },
  futuresDepth (symbol) {
    return binance.futuresDepth(symbol)
  },
  // 获取合约交易信息（交易量）
  futuresDaily () {
    return binance.futuresDaily()
  },
  // 期货账户余额和头寸
  futuresAccount () {
    /**
     * // 使用了多少保证金
     * "totalInitialMargin": "1.81039226",
     * "totalMaintMargin": "0.01606374",
     * // 总资金
     * "totalWalletBalance": "468.78001511",
     * // 总未实现利润
     * "totalUnrealizedProfit": "-0.15975857",
     * // 实际总资金
     * "totalMarginBalance": "468.62025654",
     * "totalPositionInitialMargin": "1.81039226",
     * "totalOpenOrderInitialMargin": "0.00000000",
     * "totalCrossWalletBalance": "468.78001511",
     * "totalCrossUnPnl": "-0.15975857",
     * // 可用资金
     * "availableBalance": "466.80974709",
     * "maxWithdrawAmount": "466.80974709",
     * "assets":[]
     * "positions":[]
     */
    /**
     * "symbol": "SNTUSDT",
     * // 保证金，正数
     * "initialMargin": "0",
     * "maintMargin": "0",
     * // 总未实现利润
     * "unrealizedProfit": "0.00000000",
     * "positionInitialMargin": "0",
     * "openOrderInitialMargin": "0",
     * "leverage": "20",
     * "isolated": false,
     * "entryPrice": "0.0",
     * "breakEvenPrice": "0.0",
     * "maxNotional": "25000",
     * "positionSide": "BOTH",
     * // 份额，多单是正，空单是负数
     * "positionAmt": "0",
     * // 市值，多单是正，空单是负数(包含了盈亏)
     * "notional": "0",
     * "isolatedWallet": "0",
     * "updateTime": 0,
     * "bidNotional": "0",
     * "askNotional": "0"
     */
    return binance.futuresAccount()
  },
  // 期货余额
  futuresBalance () {
    return binance.futuresBalance()
  },
  // 获得期货头寸
  futuresPositionRisk () {
    return binance.futuresPositionRisk()
  },
  // 调整杠杆(1-125倍)
  futuresLeverage (key, quantity) {
    return binance.futuresLeverage(key, quantity)
  },
  // 期货限价买入
  futuresBuy (key, quantity, price) {
    return binance.futuresBuy(key, quantity, price)
  },
  // 期货限价卖
  futuresSell (key, quantity, price) {
    //   orderId: 5532731189,
    //   symbol: 'OPUSDT',
    //   status: 'NEW',
    //   clientOrderId: 'I6d46FfTzRBBojnrtd9O2d',
    //   price: '0.0000000',
    //   avgPrice: '0.00',
    //   origQty: '3.7',
    //   executedQty: '0.0',
    //   cumQty: '0.0',
    //   cumQuote: '0.00000000',
    //   timeInForce: 'GTC',
    //   type: 'MARKET',
    //   reduceOnly: false,
    //   closePosition: false,
    //   side: 'SELL',
    //   positionSide: 'BOTH',
    //   stopPrice: '0.0000000',
    //   workingType: 'CONTRACT_PRICE',
    //   priceProtect: false,
    //   origType: 'MARKET',
    //   updateTime: 1689323145432
    return binance.futuresSell(key, quantity, price)
  },
  futuresCancel (key, orderId) {
    return binance.futuresCancel(key, {
      orderId
    })
  },
  futuresCancelAll (key) {
    return binance.futuresCancelAll(key)
  },
  futuresAllOrders () {
    // 获取当前的委托单
    return binance.futuresOpenOrders()
  },
  // futuresOpenOrders () {
  //   return binance.futuresOpenOrders()
  // },
  // 期货市价买入
  futuresMarketBuy (key, quantity) {
    /**
     * "orderId": 5346975491,
     * "symbol": "JUPUSDT",
     * "status": "NEW",
     * "clientOrderId": "vLQhi8W84al3jYR6ae9aHk",
     * "price": "0.0000000",
     * "avgPrice": "0.00",
     * "origQty": "15",
     * "executedQty": "0",
     * "cumQty": "0",
     * "cumQuote": "0.0000000",
     * "timeInForce": "GTC",
     * "type": "MARKET",
     * "reduceOnly": false,
     * "closePosition": false,
     * "side": "BUY",
     * "positionSide": "BOTH",
     * "stopPrice": "0.0000000",
     * "workingType": "CONTRACT_PRICE",
     * "priceProtect": false,
     * "origType": "MARKET",
     * "priceMatch": "NONE",
     * "selfTradePreventionMode": "EXPIRE_MAKER",
     * "goodTillDate": 0,
     * "updateTime": 1749193026118
     */
    return binance.futuresMarketBuy(key, quantity)
  },
  // 期货市价卖
  futuresMarketSell (key, quantity) {
    return binance.futuresMarketSell(key, quantity)
  },
  // 合约的订单状态
  async futuresOrderStatus (key, orderid) {
    return new Promise((resolve, reject) => {
      console.log('futuresOrderStatus', key, orderid)
      binance.futuresOrderStatus(key, {
        orderId: orderid
      }, (error, orderStatus) => {
        console.log('futuresOrderStatus-s', key, orderid)
        if (error) {
          reject(error)
        } else {
          resolve(orderStatus)
        }
      })
    })
  },
  // 订单状态
  orderStatus (key, orderid) {
    return new Promise((resolve, reject) => {
      binance.orderStatus(key, orderid, (error, orderStatus) => {
        if (error) {
          reject(error)
        } else {
          resolve(orderStatus)
        }
      })
    })
  },
  exchangeInfo () {
    return new Promise((resolve, reject) => {
      binance.exchangeInfo((error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 账户信息，基本没用
  account () {
    return new Promise((resolve, reject) => {
      binance.account((error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 现货持仓信息
  balance () {
    return new Promise((resolve, reject) => {
      binance.balance((error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 获取所有价格
  prices () {
    return new Promise((resolve, reject) => {
      binance.prices((error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 获取某个价格
  pricesByKey (key) {
    return new Promise((resolve, reject) => {
      binance.prices(key, (error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 市价买
  marketBuy (key, quantity) {
    return new Promise((resolve, reject) => {
      binance.marketBuy(key, quantity, (error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  // 市价卖
  marketSell (key, quantity) {
    return new Promise((resolve, reject) => {
      binance.marketSell(key, quantity, (error, balances) => {
        if (error) {
          reject(error)
        } else {
          resolve(balances)
        }
      })
    })
  },
  kLines (key, intervals) {
    // Intervals: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M
    return new Promise((resolve, reject) => {
      binance.candlesticks(key, intervals, (error, ticks, symbol) => {
        if (error) {
          reject(error)
        } else {
          const list = []
          ticks.forEach((v) => {
            let [time, open, high, low, close, volume, closeTime, assetVolume, trades, buyBaseVolume, buyAssetVolume, ignored] = v
            list.push({
              time,
              tradeDate: moment(time).format('YYYY-MM-DD HH:mm:ss'),
              open: parseFloat(open),
              high: parseFloat(high),
              low: parseFloat(low),
              close: parseFloat(close),
              netChangeRatio: countDifferenceRate(close, open),
              volume: parseFloat(volume),
              closeTime,
              assetVolume,
              trades,
              buyBaseVolume,
              buyAssetVolume,
              ignored
            })
          })
          resolve(list)
        }
      }, { limit: 200 })
    })
  },
  futuresKLinesAll (key, intervals, count) {
    // Intervals: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M
    return binance.futuresCandles(key, intervals, { limit: count || 500 }).then((ticks) => {
      const list = []
      // try {
      //
      // } catch (e) {
      //   console.log(key, ticks, e)
      // }
      ticks.forEach((v) => {
        let [time, open, high, low, close, volume, closeTime, assetVolume, trades, buyBaseVolume, buyAssetVolume, ignored] = v
        list.push({
          time,
          tradeDate: moment(time).format('YYYY-MM-DD HH:mm:ss'),
          open: parseFloat(open),
          high: parseFloat(high),
          low: parseFloat(low),
          close: parseFloat(close),
          netChangeRatio: countDifferenceRate(close, open),
          volume: parseFloat(volume),
          closeTime,
          assetVolume,
          trades,
          buyBaseVolume,
          buyAssetVolume,
          ignored
        })
      })
      return list
    })
  },
  kLinesAll (key, intervals, count) {
    // Intervals: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M
    return new Promise((resolve, reject) => {
      binance.candlesticks(key, intervals, (error, ticks, symbol) => {
        if (error) {
          reject(error)
        } else {
          const list = []
          ticks.forEach((v) => {
            let [time, open, high, low, close, volume, closeTime, assetVolume, trades, buyBaseVolume, buyAssetVolume, ignored] = v
            list.push({
              time,
              tradeDate: moment(time).format('YYYY-MM-DD HH:mm:ss'),
              open: parseFloat(open),
              high: parseFloat(high),
              low: parseFloat(low),
              close: parseFloat(close),
              netChangeRatio: countDifferenceRate(close, open),
              volume: parseFloat(volume),
              closeTime,
              assetVolume,
              trades,
              buyBaseVolume,
              buyAssetVolume,
              ignored
            })
          })
          resolve(list)
        }
      }, { limit: count || 500 })
    })
  }
}

module.exports = api
